package gatoropoly.ui;

import gatoropoly.game.Gatoropoly;
import gatoropoly.game.Game;
import gatoropoly.game.Player;
import gatoropoly.game.action.GatoropolyActionFactory;
import gatoropoly.game.action.GatoropolyClientAction;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JToolBar;

import modelz.UpdateListener;


public class GUI extends JFrame implements UpdateListener<Player> {

	private static final long serialVersionUID = 6009335074727417445L;

	final Gatoropoly client;

	private final JPanel leftPanel;

	private final PlayerList playerList;

	private final JTextArea chat;

	private final JMenuBar menuBar;

	private final JToolBar toolBar;

	private GUIState state;

	public GUI(Gatoropoly client) {
		super("Gatoropoly UI");

		this.client = client;

		playerList = new PlayerList(client);
		chat = new JTextArea();
		leftPanel = new JPanel();
		menuBar = new JMenuBar();

		toolBar = new JToolBar();
		toolBar.add(getAction(Gatoropoly.Action.ROLL));
		toolBar.add(getAction(Gatoropoly.Action.JAIL_ROLL));
		toolBar.add(getAction(Gatoropoly.Action.JAIL_PAY));
		toolBar.add(getAction(Gatoropoly.Action.JAIL_CARD));
		toolBar.add(getAction(Gatoropoly.Action.START_GAME));
		toolBar.add(getAction(Gatoropoly.Action.LEAVE_GAME));

		JMenu mFile = new JMenu("File");
		final Action closeAction = new AbstractAction("Close") {
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		};
		mFile.add(closeAction);
		menuBar.add(mFile);

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				closeAction.actionPerformed(null);
			}
		});

		leftPanel.setLayout(new BorderLayout());
		leftPanel.add(playerList, BorderLayout.NORTH);
		leftPanel.add(chat, BorderLayout.CENTER);

		Container c = getContentPane();
		c.setLayout(new BorderLayout());

		c.add(leftPanel, BorderLayout.WEST);
		c.add(toolBar, BorderLayout.NORTH);
		setJMenuBar(menuBar);
	}

	public void setState(GUIState state) {
		if( this.state != null )
			this.state.end(this);
		this.state = state;
		this.state.begin(this);
	}

	public void loggedIn() {
		Player self = client.getState().self();
		self.addListener(this);
	}

	public void updated(Player player) {
		Game game = player.getGame();
		if( game == null || game.getStatus() == Game.Status.NONE )
			setState(new ConnectedState(client));
		else if( game.getStatus() == Game.Status.CONFIG )
			setState(new GameConfigurationState(client));
		else if( game.getStatus() == Game.Status.RUNNING )
			setState(new PlayingState(client));
		else
			System.out.println(game.getStatus());
	}
	
	protected ClientAction<GatoropolyClientAction> getAction(
			GatoropolyActionFactory<GatoropolyClientAction> factory) {
		return new ClientAction<GatoropolyClientAction>(factory
				.getActionInstance(client));
	}

}
